﻿#pragma once

#include <iostream>
#include "libdaq/backend/backend_option.h"
#include "libdaq/device/base_device_config.h"
#include "libdaq/logger/logger.h"

#define LZ_DAQ_BASE_BACKEND_PRINT_UNSUPPORT DAQ_LIBRARY_LOGGER_CRITICAL("BaseBackend don't support this API.")

namespace libdaq {
namespace backend {
/**
 * @brief DAQ设备后端
 */
enum class LockzhinerBackendType {
  BaseBakcend,    ///< 未知后端
  USBBackend,     ///< USB后端
  SocketBackend,  ///< TCP后端
};

/**
 * @brief 后端控制基类，开发者无需关注
 *
 * 后端控制基类的函数大致分为初始化，打开，读取，写入4个部分。添加任何后端都需要重写这四个函数。
 *
 * @attention 该类文档仅供内部使用，二次开发用户无需关注该类
 * @return 默认返回值均为false或者0
 */
class LockzhinerBaseBackend {
public:
  LockzhinerBaseBackend() = default;
  virtual ~LockzhinerBaseBackend() = default;
  virtual LockzhinerBackendType GetBackendType() = 0;
  virtual bool Initialize() = 0;
  virtual bool Open() = 0;
  virtual bool Close() = 0;
  // For SocketBackend
  virtual bool ReadData(unsigned char *data, const int read_size, int *actual_size, const int duration_ms);
  virtual bool WriteData(unsigned char *data, const int write_size, int *actual_size, const int duration_ms);
  // For USBBackend
  virtual bool ReadData(uint8_t endpoint_index,
                        unsigned char *data,
                        const int read_size,
                        int *actual_size,
                        const int duration_ms);

  virtual bool WriteData(uint8_t endpoint_index,
                         unsigned char *data,
                         const int write_size,
                         int *actual_size,
                         const int duration_ms);

  [[nodiscard]] bool is_initialized() const {
    return is_initialized_;
  }

  [[nodiscard]] bool is_opened() const {
    return is_opened_;
  }

  void set_thread_safe(const bool thread_safe) {thread_safe_ = thread_safe; }
  [[nodiscard]]bool thread_safe() const {return thread_safe_;}

protected:
  bool is_initialized_ = false;
  bool is_opened_ = false;
  bool thread_safe_ = true; // 以线程安全的方式读取数据

};
} // namespace backend
} // namespace libdaq
